package com.android.telephonecall.service;

import android.app.Service;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.Cursor;
import android.net.Uri;
import android.os.IBinder;
import android.provider.CallLog;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.widget.Toast;

import androidx.annotation.Nullable;

import com.android.telephonecall.MqttClientManager;
import com.android.telephonecall.event.MqttDataEvent;
import com.android.telephonecall.event.MqttToastEvent;
import com.android.telephonecall.model.MqttCallLogModel;
import com.android.telephonecall.model.MqttCommandModel;
import com.android.telephonecall.receiver.FileCreationReceiver;
import com.android.telephonecall.utils.AndroidUtils;
import com.android.telephonecall.utils.DeviceInfoManager;
import com.android.telephonecall.utils.EventBusHelper;
import com.android.telephonecall.utils.JsonUtils;
import com.android.telephonecall.utils.MqttAction;

import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.text.SimpleDateFormat;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

public class MainService extends Service {

    private static final String TAG = "MainService";

    private TelephonyManager mTelephonyManager;
    private PhoneStateListener mPhoneStateListener;
    private String mPhoneNumber;
    private FileCreationReceiver fileCreationReceiver;

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "onCreate: ");
        //注册EventBus
        EventBusHelper.register(this);

        initData();
    }

    private void initData() {
        mTelephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);

        //获取电话号码
        mPhoneNumber = mTelephonyManager.getLine1Number();
        Log.d(TAG, "initData getPhoneNumber: " + mPhoneNumber);
        // 注册广播接收器
        fileCreationReceiver = new FileCreationReceiver();
        IntentFilter filter = new IntentFilter(Intent.ACTION_CREATE_DOCUMENT);
        registerReceiver(fileCreationReceiver, filter);

//        makePhoneCall("13755879783","13717013525");
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "onDestroy: ");
        //取消注册EventBus
        EventBusHelper.unregister(this);
        // 停止监听通话状态
        if (mTelephonyManager != null) {
            mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
        }
        // 取消注册广播接收器
        if (fileCreationReceiver != null) {
            unregisterReceiver(fileCreationReceiver);
        }

    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        throw new RuntimeException("Unsupported operate!");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(TAG, "onStartCommand: ");
        return START_STICKY;
    }



    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMqttGetDataEvent(MqttDataEvent event) {
        String message = event.getMessage();
        MqttCommandModel mqttCommandModel = JsonUtils.tryParseJson(message, MqttCommandModel.class);
        if (mqttCommandModel != null) {
            Log.d(TAG, "onMqttGetDataEvent message: " + message
                    + " mqttCommandModel:" + mqttCommandModel.toString());
            String requestId = mqttCommandModel.getRequestId();
            String timestamp = mqttCommandModel.getTimestamp();
            String action = mqttCommandModel.getAction();
            long receivedTimestamp = Long.parseLong(timestamp);
            long currentTimestamp = System.currentTimeMillis();
            if (currentTimestamp - receivedTimestamp > 2 * 60 * 1000) {
                // 时间差超过2分钟，过滤不接收 反馈消息已经过期
                MqttCommandModel commandModel = new MqttCommandModel();
                commandModel.setRequestId(requestId);
                commandModel.setTimestamp(timestamp);
                commandModel.setAction(action);
                MqttCommandModel.ParamBean paramBean = new MqttCommandModel.ParamBean();
                paramBean.setCode(500);
                paramBean.setMsg("消息已经过期");
                commandModel.setParam(paramBean);
                String expireJsonStr = JsonUtils.toJson(commandModel);

                MqttClientManager.getInstance().publishMessage(MqttClientManager.PUBLISH_TOPIC,expireJsonStr.getBytes()
                        ,action);
                return;
            }
            // 时间差未超过2分钟，继续接收
            switch (action) {
                case MqttAction.ACTION_PHONE_INFO:
                    MqttCommandModel.ParamBean infoParam = mqttCommandModel.getParam();

                    break;
                case MqttAction.ACTION_CALL_STATUS:
                    MqttCommandModel.ParamBean callParam = mqttCommandModel.getParam();

                    break;
                case MqttAction.ACTION_UPLOAD_RECORD:
                    MqttCommandModel.ParamBean recordParam = mqttCommandModel.getParam();

                    break;
                case MqttAction.ACTION_DIALING:
                    MqttCommandModel.ParamBean dialingParam = mqttCommandModel.getParam();
                    String fromNumber = dialingParam.getFromNumber();
                    String toNumber = dialingParam.getToNumber();
                    Log.d(TAG, "onMqttGetDataEvent fromNumber: " + fromNumber
                            + " toNumber:" + toNumber);
                    makePhoneCall(toNumber,fromNumber);

                    break;
                case MqttAction.ACTION_UPLOAD_FILE_RESULT:
                    //通知录音文件上传结果
                    MqttCommandModel.ParamBean updateFileParam = mqttCommandModel.getParam();
                    String recordId = updateFileParam.getRecordId();
                    int status = updateFileParam.getStatus();
                    Log.d(TAG, "onMqttGetDataEvent recordId: " + recordId
                            + " status:" + status);

                    break;
            }
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMqttShowToastEvent(MqttToastEvent event) {
        boolean success = event.isSuccess();
        String message = event.getMessage();
        Toast.makeText(this , message, Toast.LENGTH_SHORT).show();

        if (success) {
            //发送登录请求
            MqttCommandModel commandModel = new MqttCommandModel();
            commandModel.setRequestId(UUID.randomUUID().toString());
            commandModel.setTimestamp(AndroidUtils.getTimeStamp());
            commandModel.setDeviceId(DeviceInfoManager.getInstance().getDeviceId());
            commandModel.setAction(MqttAction.ACTION_PHONE_INFO);
            MqttCommandModel.ParamBean paramBean = new MqttCommandModel.ParamBean();
            paramBean.setInfo(DeviceInfoManager.getInstance().getPhoneModel()
                    + "、" + DeviceInfoManager.getInstance().getAndroidVersion());
            paramBean.setVersion(DeviceInfoManager.getInstance().getAppVersion());
            paramBean.setNumbers(mPhoneNumber);
            commandModel.setParam(paramBean);
            String loginJsonStr = JsonUtils.toJson(commandModel);

            MqttClientManager.getInstance().publishMessage(MqttClientManager.PUBLISH_TOPIC,loginJsonStr.getBytes()
                    ,MqttAction.ACTION_PHONE_INFO);
        }
    }

    //拨号
    private void makePhoneCall(String phoneNumber,String destinationNumber) {
        // 检查设备是否支持拨号功能
        if (mTelephonyManager != null && mTelephonyManager.getPhoneType()
                != TelephonyManager.PHONE_TYPE_NONE) {

            Intent intent = new Intent(Intent.ACTION_CALL);
            intent.setData(Uri.parse("tel:" + phoneNumber));
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.putExtra("com.android.phone.extra.GATEWAY_URI", Uri.parse("tel:" + destinationNumber));
            startActivity(intent);
        } else {
            // 设备不支持拨号功能，进行相应处理
            Toast.makeText(this,"设备不支持拨号功能!",Toast.LENGTH_SHORT).show();
        }
    }

    // 获取通话状态
    private void getCallState() {
        mPhoneStateListener = new PhoneStateListener() {
            @Override
            public void onCallStateChanged(int state, String phoneNumber) {
                super.onCallStateChanged(state, phoneNumber);

                //通话状态回调
                MqttCommandModel callStatusCommandModel = new MqttCommandModel();
                callStatusCommandModel.setRequestId(UUID.randomUUID().toString());
                callStatusCommandModel.setTimestamp(AndroidUtils.getTimeStamp());
                callStatusCommandModel.setDeviceId(DeviceInfoManager.getInstance().getDeviceId());
                callStatusCommandModel.setAction(MqttAction.ACTION_CALL_STATUS);
                MqttCommandModel.ParamBean paramBean = new MqttCommandModel.ParamBean();
                Log.d(TAG, "onCallStateChanged state: " + state
                        + " phoneNumber:" + phoneNumber);
                switch (state) {
                    case TelephonyManager.CALL_STATE_IDLE:
                        Log.d(TAG, "onCallStateChanged: 无任何活动 ");
                        paramBean.setStatus(1);
                        paramBean.setLocalNumber(mPhoneNumber);
                        break;
                    case TelephonyManager.CALL_STATE_OFFHOOK:
                        Log.d(TAG, "onCallStateChanged: 电话接通 ");
                        paramBean.setStatus(2);
                        paramBean.setLocalNumber(mPhoneNumber);
                        paramBean.setNumber(phoneNumber);
                        break;
                    case TelephonyManager.CALL_STATE_RINGING:
                        Log.d(TAG, "onCallStateChanged: 电话响铃 ");
                        paramBean.setType(1);
                        paramBean.setLocalNumber(mPhoneNumber);
                        paramBean.setNumber(phoneNumber);
                        break;
                }
                callStatusCommandModel.setParam(paramBean);
                String callStatusJsonStr = JsonUtils.toJson(callStatusCommandModel);
                MqttClientManager.getInstance().publishMessage(MqttClientManager.PUBLISH_TOPIC,callStatusJsonStr.getBytes()
                        ,MqttAction.ACTION_CALL_STATUS);

                //通话记录上传
                MqttCallLogModel callLogCommandModel = new MqttCallLogModel();
                callLogCommandModel.setRequestId(UUID.randomUUID().toString());
                callLogCommandModel.setTimestamp(AndroidUtils.getTimeStamp());
                callLogCommandModel.setDeviceId(DeviceInfoManager.getInstance().getDeviceId());
                callLogCommandModel.setAction(MqttAction.ACTION_UPLOAD_RECORD);
                List<MqttCallLogModel.ParamBean> callLogCommandModelParams = callLogCommandModel.getParams();
                if (callLogCommandModelParams == null) {
                    callLogCommandModelParams = new ArrayList<>();
                }

                //获取通话记录
                List<Map<String, String>> dataList = getDataList();
                for (Map<String, String> stringStringMap : dataList) {
                    MqttCallLogModel.ParamBean callLogParam = new MqttCallLogModel.ParamBean();
                    for (Map.Entry<String, String> stringStringEntry : stringStringMap.entrySet()) {
                        String key = stringStringEntry.getKey();
                        String value = stringStringEntry.getValue();
//                        if (key.equals("通话号码")) {
//                            callLogParam.setPhoneNumber(value);
//                        }
                        if (key.equals("通话时长")) {
                            callLogParam.setPhoneDuration(value);
                        }
                        if (key.equals("通话时间")) {
                            callLogParam.setPhoneDate(value);
                        }
                        if (key.equals("联系人姓名")) {
                            callLogParam.setPhoneName(value);
                        }
                        if (key.equals("通话类型")) {
                            callLogParam.setPhoneType(value);
                        }
                    }
                    callLogCommandModelParams.add(callLogParam);
                    Log.d(TAG, "----------onCallStateChanged----------------- ");
                }
                for (int j = 0; j < callLogCommandModelParams.size(); j++) {
                    MqttCallLogModel.ParamBean recordLog = callLogCommandModelParams.get(j);
                    recordLog.setRecordId(String.valueOf(j));
                    Log.d(TAG, "onCallStateChanged recordLog: " + recordLog.toString());
                }
                callLogCommandModel.setParams(callLogCommandModelParams);
                String callLogJsonStr = JsonUtils.toJson(callLogCommandModel);
                MqttClientManager.getInstance().publishMessage(MqttClientManager.PUBLISH_TOPIC,callLogJsonStr.getBytes()
                        ,MqttAction.ACTION_UPLOAD_RECORD);
            }
        };
        mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
    }

    /**
     * 获取通话记录
     *
     * @return 读取到的数据
     */
    private List<Map<String, String>> getDataList() {
        // 1.获得ContentResolver
        ContentResolver resolver = getContentResolver();
        // 2.利用ContentResolver的query方法查询通话记录数据库
        /**
         * @param uri 需要查询的URI，（这个URI是ContentProvider提供的）
         * @param projection 需要查询的字段
         * @param selection sql语句where之后的语句
         * @param selectionArgs ?占位符代表的数据
         * @param sortOrder 排序方式
         *
         */
        Cursor cursor = resolver.query(CallLog.Calls.CONTENT_URI, // 查询通话记录的URI
                new String[] { CallLog.Calls.CACHED_NAME// 通话记录的联系人
                        , CallLog.Calls.NUMBER// 通话记录的电话号码
                        , CallLog.Calls.DATE// 通话记录的日期
                        , CallLog.Calls.DURATION// 通话时长
                        , CallLog.Calls.TYPE// 通话类型
                }
                , null, null, CallLog.Calls.DEFAULT_SORT_ORDER// 按照时间逆序排列，最近打的最先显示
        );
        // 3.通过Cursor获得数据
        List<Map<String, String>> list = new ArrayList<Map<String, String>>();
        while (cursor.moveToNext()) {
            String name = cursor.getString(cursor.getColumnIndex(CallLog.Calls.CACHED_NAME));
            String number = cursor.getString(cursor.getColumnIndex(CallLog.Calls.NUMBER));
            long dateLong = cursor.getLong(cursor.getColumnIndex(CallLog.Calls.DATE));
            String date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(dateLong));
            int duration = cursor.getInt(cursor.getColumnIndex(CallLog.Calls.DURATION));
            int type = cursor.getInt(cursor.getColumnIndex(CallLog.Calls.TYPE));
            String typeString = "";
            switch (type) {
                case CallLog.Calls.INCOMING_TYPE:
                    typeString = "打入通话";
                    break;
                case CallLog.Calls.OUTGOING_TYPE:
                    typeString = "打出通话";
                    break;
                case CallLog.Calls.MISSED_TYPE:
                    typeString = "未接通话";
                    break;
                case CallLog.Calls.REJECTED_TYPE:
                    typeString = "拒接通话";
                    break;
                case CallLog.Calls.BLOCKED_TYPE:
                    typeString = "屏蔽通话";
                    break;
                default:
                    break;
            }
            Map<String, String> map = new HashMap<String, String>();
            map.put("联系人姓名", (name == null) ? "未备注联系人" : name);
            map.put("通话号码", number);
            map.put("通话时间", date);
            map.put("通话时长", String.valueOf(duration));
            map.put("通话类型", typeString);
            list.add(map);
        }
        return list;
    }
}
